#! /usr/bin/python

from events import *
import preferences
import random
import copy


DIRECTION_UP = 0
DIRECTION_DOWN = 1
DIRECTION_LEFT = 2
DIRECTION_RIGHT = 3

#------------------------------------------------------------------------------
class Game:
        

        STATE_PREPARING = 0
        STATE_RUNNING = 1
        STATE_PAUSED = 2

#----------------------------------------------------------------------
	# O atributo 'decisor' diz se a instancia de Game
	# pode ou nao tomar decisoes globais sobre o jogo
	# como por exemplo o dono de cada territorio
        def __init__(self, evManager, decisor = False):
                self.evManager = evManager
                self.evManager.RegisterListener( self )
		self.decisor = decisor
                self.Reset()
		self.maxplayers = 4

#----------------------------------------------------------------------

        def determinar_dono_territorio (self, territorio):
                return territorio.getPosseDeTerritorio

	def CreateCurrentPlayerDict(self):
		if not self.decisor:
			dic =  {'name' : self.current_player, 'color' : self.current_player_color}
			return dic
		else:
			return None
#----------------------------------------------------------------------
	def distribuirTerritorios(self):
		lands = copy.deepcopy(preferences.gameLands)
		numplayers = len(self.players)
		numlands   = len(lands)
		extras = numlands % numplayers
		slice = numlands / numplayers
		random.shuffle(lands)
		
		for p in reversed(self.players):
			if extras > 0:
				to_give, lands = lands[0:slice+1], lands[slice+1:]
				extras -= 1
			else:
				to_give, lands = lands[0:slice], lands[slice:]
			for l in to_give:
				p.add_territory(l, 3)
			self.territories_by_player[p.GetName()] = to_give
#----------------------------------------------------------------------
	def isEverybodyReady(self):
		if len(self.players) > 1:
			for p in self.players:
				if not p.get_ready():
					return False
			return True
		else:
			return False
#----------------------------------------------------------------------

        def realizar_ataque(self, territorio_ataque, territorio_defesa):
                max = 3
                venceu = False 
                x = territorio_ataque.getQuantidadeDeExercito
                y = territorio_defesa.getQuantidadeDeExercito
		retorno =[]
                self.dado_a =[]
                self.dado_d = []
                #verifica se o atacante tem mais de 1 exercito
                if x > 1:
                        if x <= max +1:
                                num_dados_ataque = x -1 
                        else:   num_dados_ataque = max
                        if y <= max:
                                num_dados_defesa = y
                        else: num_dados_defesa = max
                        for i in range (num_dados_ataque):
                        #sorteio dados ataque
                                self.dado_a.append(random.randint(1,6))
                        for i in range (num_dados_defesa):
                        #sorteio dados defesa
                                self.dado_d.append(random.randint(1,6))
                        # orndeno os dados numa lista por ordem decrescente
                        self.dado_a.reverse()
                        self.dado_d.reverse()
                        vit = 0
                        der = 0
                        i=0
                        while dado_d != null:
                                #comparo os dados de ataque e defesa
                                if dado_a[i] > dado_d[i]:
                                        vit = vit + 1
                                else:   
                                        der = der + 1
                                        
                        # Ja seta aqui a quantidade de exercitos nos dois territorios envolvidos, depois de um ataque           
                        x = x - der
                        y = y - vit
                        #verifico se soborou 0 exercitos no territorio de defesa
                        if y <= 0:
                                venceu = true
			retorno.append(venceu)
			retorno.append(self.dado_a)
			retorno.append(self.dado_d)
			return retorno

                
                else:
                        mensagem = 'Nao ha numero de exercitos suficiente para realizar ataque'
                	return mensagem
#----------------------------------------------------------------------
        def Reset( self ):
                self.state = Game.STATE_PREPARING
                
                self.players = [ ]
                self.maxPlayers = 6
                self.map = Map( self.evManager )

                self.player_by_name = {}
		self.territories_by_player = {}

		self.current_player = ''
                self.turno = ''

		self.current_player = ''
		self.current_player_color = 'black' #default color

		self.num_exercitos_territorio = {}


#----------------------------------------------------------------------
        def Start(self):
                self.map.Build()
                self.state = Game.STATE_RUNNING
                ev = GameStartedEvent( self )

                self.player_by_name = {}
		print "Here"

                self.evManager.Post( ev )
	
	def GetCurrentPlayer(self):
		if not self.decisor:
			return self.current_player
		else:
			raise Exception("Current player doesn't exist")
	
	def GetPlayers(self):
		return self.players

	def GetCurrentPlayerColor(self):
		if not self.decisor:
			return self.current_player_color
		else:
			raise Exception("Current player doesn't exist")

	def GetCurrentPlayerTerritories(self):
		if not self.decisor:
			return self.player_by_name[self.current_player].GetTerritories()
		else:
			raise Exception("Current player doesn't exist")

#----------------------------------------------------------------------
        def AddPlayer(self, player):

		if player.GetName() in self.player_by_name:
			raise Exception("Nome ja escolhido")
		
		if player.GetName() == "":
			raise Exception("O nome precisa conter pelo menos um caractere")

		for p in self.players:
			if player.GetColor() == p.GetColor():
				raise Exception("Cor ja escolhida")

		

               	self.players.append( player )
               	player.SetGame( self )
		self.player_by_name[player.GetName()] = player
               	ev = PlayerJoinEvent( player )
               	self.evManager.Post( ev )



#----------------------------------------------------------------------
        def Notify(self, event):

                if isinstance( event, GamePrepareRequest):
                        if self.current_player == "":
                                ev = GUIDialogAddRequest('msgDialog', 'O nome precisa conter pelo menos um caractere.')
                                self.evManager.Post( ev )
                        else:
				ev = RegisterToTheServerEvent()
				self.evManager.Post( ev )
                                #ev = GUIWaitingDialogAddRequest('waitingDialog')
                                #self.evManager.Post( ev )


                if isinstance( event, GameStartRequest ):
                        if self.state == Game.STATE_PREPARING:
                                self.Start()
                        elif self.state == Game.STATE_RUNNING:
                                self.Reset()
                                self.Start()

                if isinstance( event, PlayerJoinRequest ):
                        if len(self.players) < self.maxplayers:
				playerDict = event.playerDict
                                player = Player( self.evManager, playerDict['name'], playerDict['color'], '')
                                for p in self.players:
                                        if p.name == player.name:
                                                #FAIL
                                                raise NotImplementedError, "Dup player"
                                self.AddPlayer( player )

                if isinstance( event, GUIChangeScreenRequest ):
                        ev = GameSyncEvent( self )
                        self.evManager.Post( ev )

		if isinstance( event, SetCurrentPlayerNameEvent ):
			self.current_player = event.player_name

		if isinstance( event, SetCurrentPlayerColorEvent ):
			self.current_player_color = event.color

		if isinstance( event, GameSetupRequest ):
			#self.Reset()
			self.state = Game.STATE_PREPARING
			for k, v in event.dic.items():
				name, color = k.split(':')
				territories = v
				player = Player(self.evManager, name, color, '')
				self.AddPlayer(player)
				for t in territories:
					t = t.split(':')
					numexe = int(t[2])
					t = [int(t[0]), int(t[1])]
					player.add_territory(t, numexe)
				self.territories_by_player[name] = player.GetTerritories()
			self.evManager.Post( GameStartRequest() )

#------------------------------------------------------------------------------
class Player:
        """..."""
        def __init__(self, evManager, name, color, ip ):
                self.evManager = evManager
                self.game = None
                self.name = name
		self.color = color
                self.ip = ip
                self.cartas = []
                self.evManager.RegisterListener( self )
		self.territorios = []
		self.ready = False

                #self.charactors = [ Customer(evManager) ]
                #self.placeableCharactorClasses = [ Charactor ]
                #self.startSector = None

#----------------------------------------------------------------------

	def set_ready(self, val):
		self.ready = val
		if self.game:
			if self.game.isEverybodyReady():
				return True
		return False
	
	def get_ready(self):
		return self.ready


        def listar_territorios(self, lista_de_territorios = []):
                self.territorios = lista_de_territorios
                if self.territorios == None:
                        print 'O jogador nao possui territorios'
                else: 
                        i = 0
                        while lista_de_territorios:
                                print lista_de_territorios[i]
                                i= i + 1

#----------------------------------------------------------------------

        def add_carta(self, carta):
                self.cartas.append(carta)

	def add_territory(self, territory, num = 1):
		self.territorios.append(territory)
		self.game.num_exercitos_territorio[tuple(territory)] = num

	def GetTerritories(self):
		return self.territorios

	def GetName(self):
		return self.name

	def GetColor(self):
		return self.color

#----------------------------------------------------------------------
        def GetPlaceData( self ):
                charactor = self.charactors[0]
                map = self.game.map
                sector =  map.sectors[map.startSectorIndex]
                return [charactor, sector]

#----------------------------------------------------------------------
        def GetMoveData( self ):
                return [self.charactors[0]]

#----------------------------------------------------------------------
        def SetGame( self, game ):
                self.game = game

        #----------------------------------------------------------------------
        def SetData( self, playerDict ):
                self.name = playerDict['name']
		self.color = playerDict['color']

        #----------------------------------------------------------------------
        def Notify(self, event):
                pass
                #if isinstance( event, jogadorJoinEvent):
                        #if event.jogador is self:

#------------------------------------------------------------------------------

class territorio:

        def __init__(self, nome):
                self.nome = nome
                self.quantidadeDeExercitos = 0
                self.donoTerritorio = ''
		self.adjacencias=[]
	
        #---------------------------------------------------------------------
        def setQuantidadeDeExercito(self, quantidade):
                self.quantidadeDeExercitos = quantidade
        
        #---------------------------------------------------------------------
	def add_Exercito(self):
		self.quantidadeDeExercitos += 1
	
        #---------------------------------------------------------------------	
	def add_Adjacencia(self,territorio):
		self.adjacencias.append(territorio)
        
        #---------------------------------------------------------------------
        def getQuantidadeDeExercitos(self):
                return quantidadeDeExercitos

        #---------------------------------------------------------------------
        def setPosseTerritorio(self, jogador):
                self.donoTerritorio = jogador

        #---------------------------------------------------------------------
        def getPosseTerritorio(self):
                return donoTerritorio



#------------------------------------------------------------------------------
class MapaMundi:
	def __init__(self):
		self.territorios=[]

        #---------------------------------------------------------------------	
	def add_Territorio(self,territorio):
		self.territorios.append(territorio)

        #---------------------------------------------------------------------
	def ehAdjacente(self,territorio1,territorio2):
		if territorio2 in territorio1.adjacencias:
			return True
		else:
			return False




#------------------------------------------------------------------------------



class CE(territorio):
        def __init__(self, nome):
                territorio.__init__(self, nome)

#------------------------------------------------------------------------------


class Comum(territorio):
        def __init__(self, nome):
                territorio.__init__(self, nome)

#------------------------------------------------------------------------------
class Map:
        """..."""

        STATE_PREPARING = 0
        STATE_BUILT = 1


        #----------------------------------------------------------------------
        def __init__(self, evManager):
                self.evManager = evManager
                self.evManager.RegisterListener( self )
                self.state = Map.STATE_PREPARING

                self.sectors = range(0)

        #----------------------------------------------------------------------
        def Build(self):
                #for i in range(3):
                #       self.sectors[i] = Sector( self.evManager )
                self.state = Map.STATE_BUILT
                #ev = MapBuiltEvent( self )
                #self.evManager.Post( ev )

        #----------------------------------------------------------------------
        def Notify(self, event):
                if isinstance( event, CharactorPlaceEvent ):
                        sect = event.charactor.sector
                        #self.startSectorIndex = self.sectors.index(sect)+1

#------------------------------------------------------------------------------
class Sector:
        """..."""
        def __init__(self, evManager):
                self.evManager = evManager
                #self.evManager.RegisterListener( self )

                self.neighbors = range(4)

                self.neighbors[DIRECTION_UP] = None
                self.neighbors[DIRECTION_DOWN] = None
                self.neighbors[DIRECTION_LEFT] = None
                self.neighbors[DIRECTION_RIGHT] = None

        #----------------------------------------------------------------------
        def MovePossible(self, direction):
                if self.neighbors[direction]:
                        return 1


if __name__ == "__main__":
        print "wasn't expecting that"
